
import Foundation
import Flutter
import UIKit
import StoreKit
import AppTrackingTransparency

import ZegoExpressEngine
public class LiveMessagePlugin :NSObject, ZegoEventHandler{

    var mMessageChannel:FlutterBasicMessageChannel
    var mFlutterCV:FlutterViewController
 
    var livePreviewMap :Dictionary<Int,LivePreviewView> = [:]
     

    var appConfig :AppConfig?
    var roomInfo :RoomInfo?
    var roomData :RoomDataModel?
      
 
    var previewView: UIView?
    init(controller :FlutterViewController){
        mFlutterCV=controller
        mMessageChannel = FlutterBasicMessageChannel(name: "LiveMessagePlugin", binaryMessenger: controller.binaryMessenger)
        super.init()  // 应该先调用父类初始化器
        mMessageChannel.setMessageHandler { [weak self] (message, reply) in
            guard let self = self else { return }
            
            if let args = message as? [String: Any] {
                
                let method = args["method"] as? String ?? ""
                let action = args["action"] as? String ?? ""
                let viewId = args["viewId"] as? String ?? ""
                let data = args["data"] as? String ?? ""
                
                switch method {
                case "zegoInit":
                    zegoInit(data: data, reply: reply)
                case "loginRoom":
                    loginRoom(data: data, reply: reply)
                case "logoutRoom":
                    logoutRoom(data: data, reply: reply)
                case "refreshMaiInfo":
                    refreshMaiInfo(data: data, reply: reply)
                default:
                    reply(FlutterMethodNotImplemented)
                }
            } else {
                reply(FlutterError(code: "INVALID_ARGUMENT", message: "Invalid message format", details: nil))
            }
        }
    }
    
    func zegoInit(data: String , reply: FlutterReply ){
        if let appConfig :AppConfig = parseJSON(jsonString: data, to: AppConfig.self){
            self.appConfig = appConfig
            let profile = ZegoEngineProfile()
            profile.appID = UInt32(appConfig.jgAppId  )!
            profile.appSign = appConfig.jgAppSign
             
            // please refer to https://docs.zegocloud.com/article/14940
            profile.scenario = .broadcast
            ZegoExpressEngine.createEngine(with: profile, eventHandler: self)

            ZegoExpressEngine.shared().enableHardwareEncoder(true)
            reply(result(0,0,"success"))
        }else {
            reply(result(-1,0,"appconfig 参数未传"))
        }
    }
    func loginRoom(data: String , reply: FlutterReply ){
        if let roomInfo :RoomInfo = parseJSON(jsonString: data, to: RoomInfo.self){
            self.roomInfo = roomInfo
            let config = ZegoRoomConfig()
    //        config.token = KeyCenter.token
            
            ZegoExpressEngine.shared().loginRoom(String(roomInfo.id ?? 0), user: ZegoUser(userID: String(roomInfo.selfUserId ?? 0)), config: config)
            
            reply(result(0,0,"success"))
        }else {
            reply(result(-1,0,"RoomInfo 参数未传"))
        }
    }
    func logoutRoom(data: String , reply: FlutterReply ){
             
        ZegoExpressEngine.shared().stopPreview()
        ZegoExpressEngine.shared().stopPublishingStream()
        ZegoExpressEngine.shared().logoutRoom()
            reply(result(0,0,"success"))
      
    }
     
     
    
    func refreshMaiInfo(data: String , reply: FlutterReply ){
        if let roomData :RoomDataModel = parseJSON(jsonString: data, to: RoomDataModel.self){
            self.roomData = roomData
    //        config.token = KeyCenter.token
            
            var stopPush = true //默认停止推流。
            for   item in roomData.roomMais {
//                if item.isAnchor() && !item.inputStreamId.isEmpty {//自己在麦位上面,并且有分配流。
                if item.isAnchor() && item.status != 0 {//自己在麦位上面, status 等于0一般表示下麦。
                    stopPush = false;
                }
                if  let liveView = livePreviewMap[item.maiIndex]{
                  liveView.roomMais = item
                    if !item.inputStreamId.isEmpty || !item.outputStreamId.isEmpty{                        
                        liveView.startPreview()
                    }
                }
            }
            if stopPush { //防止内存泄露，比如 后台把麦位清空了。下麦。都自动处理。
                ZegoExpressEngine.shared().stopPublishingStream()
                ZegoExpressEngine.shared().stopPreview()
            }
            
            reply(result(0,0,"success"))
        }else {
            reply(result(-1,0,"RoomInfo 参数未传"))
        }
    }
     
  
 
    
    func result(_ code:Int,_ errorCode:Int,_ msg:String?) -> String?{
        var result:Dictionary<String,Any?> = [
            "code":code,
            "errorCode":code,
            "msg":msg,
        ]
        return dictionaryToJSONString(result)
    }
    
}



// 将字典转换为 JSON 字符串的函数
func dictionaryToJSONString(_ dictionary: Dictionary<String, Any?>) -> String? {
    do {
        // 使用 JSONSerialization 将字典转换为 JSON 数据
        let jsonData = try JSONSerialization.data(withJSONObject: dictionary.compactMapValues { $0 }, options: .prettyPrinted)
        
        // 将 JSON 数据转换为 JSON 字符串
        let jsonString = String(data: jsonData, encoding: .utf8)
        
        return jsonString
    } catch {
        print("字典转换为 JSON 字符串失败: \(error)")
        return nil
    }
}


// 通用的解析方法，返回泛型对象
func parseJSON<T: Decodable>(jsonData: Data, to type: T.Type) -> T? {
    let decoder = JSONDecoder()
    do {
        let decodedObject = try decoder.decode(T.self, from: jsonData)
        return decodedObject
    } catch {
        print("解析失败: \(error)")
        return nil
    }
}

// 便捷的JSON字符串解析方法
func parseJSON<T: Decodable>(jsonString: String, to type: T.Type) -> T? {
    if let data = jsonString.data(using: .utf8) {
        return parseJSON(jsonData: data, to: type)
    }
    return nil
}


